package person.rk.simfnc.common

object Util {
    data class ByteSlice(val base: ByteArray, val startIdx: Int = 0, val endIdx: Int = -1){
        val size: Int
            get() = _realEndIdx - _realStartIdx

        val content: List<Byte>
            get() = base.slice(_realStartIdx ..< _realEndIdx)

        val head: Byte = base[startIdx]

        operator fun get(i: Int): Byte{
            if (i in 0 ..< size){
                return base[_realStartIdx + i]
            }
            else
                throw IndexOutOfBoundsException()
        }

        fun readShort(fromIdx: Int, endian: String="big"): Short{
            val b1 = get(fromIdx)
            val b2 = get(fromIdx + 1)
            return mkShort(b1, b2, endian)
        }


        fun slice(i1: Int = 0, i2: Int = -1): ByteSlice {
            val xi1 = if(i1 < 0) 0 else i1

            val lx = if (i2 >= 0) {
                if (i2 >= xi1)
                    i2 - xi1
                else
                    0
            } else {
                val t = size + i2
                if (t < 0)
                    0
                else
                    t
            }

            return ByteSlice(base, _realStartIdx + xi1, xi1 + lx)
        }

        private val _realStartIdx = if (startIdx < 0) 0 else startIdx
        private val _realEndIdx = if (endIdx < 0 || endIdx > base.size) base.size else endIdx
    }

    fun mkShort(b1: Byte, b2: Byte, endian: String): Short{
        if (endian.lowercase().startsWith("big")){
            return ((b1.toInt() shl 8) + b2.toInt()).toShort()
        }
        return ((b2.toInt() shl 8) + b1.toInt()).toShort()
    }

    fun mkInt(b1: Byte, b2: Byte, b3: Byte, b4: Byte, endian: String): Int{
        if (endian.lowercase().startsWith("big")){
            return (b1.toInt() shl 24) + (b2.toInt() shl 16) + (b3.toInt() shl 8) + b4.toInt()
        }
        return (b4.toInt() shl 24) + (b3.toInt() shl 16) + (b2.toInt() shl 8) + b1.toInt()
    }

}